Create an interactive report

Choose a dataset!

You can use any dataset for this task accessible by the pandas-datareader module. You should explain what the dataset is about and which part of it will you visualize!

If the pandas-datareader package is not available in your notebook, then either stop, delete and restart your course container on the Kooplex hub page, or install into your userspace

pip install --user pandas-datareader

Create with the chosen dataset

When you finished with the notebook, then

  • convert it to html jupyter-nbconvert --execute worksheet-interactive.ipynb
  • or use the Jupyter book format!

You can find further interactive tools on the pyviz site:

In [1]:
!pip install --user pandas-datareader
Requirement already satisfied: pandas-datareader in /home/c0ko9h/.local/lib/python3.7/site-packages (0.9.0)
Requirement already satisfied: pandas>=0.23 in /opt/conda/lib/python3.7/site-packages (from pandas-datareader) (1.0.1)
Requirement already satisfied: lxml in /opt/conda/lib/python3.7/site-packages (from pandas-datareader) (4.6.3)
Requirement already satisfied: requests>=2.19.0 in /opt/conda/lib/python3.7/site-packages (from pandas-datareader) (2.25.1)
Requirement already satisfied: python-dateutil>=2.6.1 in /opt/conda/lib/python3.7/site-packages (from pandas>=0.23->pandas-datareader) (2.8.1)
Requirement already satisfied: pytz>=2017.2 in /opt/conda/lib/python3.7/site-packages (from pandas>=0.23->pandas-datareader) (2021.1)
Requirement already satisfied: numpy>=1.13.3 in /opt/conda/lib/python3.7/site-packages (from pandas>=0.23->pandas-datareader) (1.19.2)
Requirement already satisfied: six>=1.5 in /opt/conda/lib/python3.7/site-packages (from python-dateutil>=2.6.1->pandas>=0.23->pandas-datareader) (1.15.0)
Requirement already satisfied: urllib3<1.27,>=1.21.1 in /opt/conda/lib/python3.7/site-packages (from requests>=2.19.0->pandas-datareader) (1.26.4)
Requirement already satisfied: idna<3,>=2.5 in /opt/conda/lib/python3.7/site-packages (from requests>=2.19.0->pandas-datareader) (2.10)
Requirement already satisfied: chardet<5,>=3.0.2 in /opt/conda/lib/python3.7/site-packages (from requests>=2.19.0->pandas-datareader) (3.0.4)
Requirement already satisfied: certifi>=2017.4.17 in /opt/conda/lib/python3.7/site-packages (from requests>=2.19.0->pandas-datareader) (2020.12.5)
In [2]:
import pandas_datareader.data as pdr
import datetime
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import plotly.graph_objects as py
import plotly.express as px
#import ipywidgets as wg

Load HUF/CHF excahge values:

In [3]:
start = datetime.datetime(2015, 1, 1)
end = datetime.datetime(2021, 1, 27)

Change = pdr.DataReader('HUF/CHF', 'av-forex-daily', start, end, api_key = 'ALPHAVANTAGE_API_KEY')
Change
Out[3]:
open high low close
2015-01-01 0.00385 0.00385 0.00379 0.00380
2015-01-02 0.00380 0.00380 0.00376 0.00377
2015-01-05 0.00377 0.00378 0.00375 0.00377
2015-01-06 0.00377 0.00378 0.00374 0.00375
2015-01-07 0.00375 0.00377 0.00374 0.00377
... ... ... ... ...
2021-01-21 0.00301 0.00302 0.00301 0.00302
2021-01-22 0.00302 0.00302 0.00301 0.00301
2021-01-25 0.00301 0.00302 0.00301 0.00301
2021-01-26 0.00301 0.00301 0.00300 0.00300
2021-01-27 0.00300 0.00300 0.00298 0.00298

1585 rows × 4 columns

In [4]:
HC_open = Change.values[:,0]
HC_high = Change.values[:,1]
HC_low = Change.values[:,2]
HC_close = Change.values[:,3]
t = Change.index.values

The exchange rate for the entire time scale. You can select the highest and lowest values ​​of the day and the opening and closing values:

In [5]:
fig = py.Figure()
fig.update_layout(autosize=False, width=1000, height=500)

change = [HC_open, HC_close, HC_high, HC_low]
name = ["Opening value", "Closing value", "Daily high value", "Daily low value"]

for i in np.arange(0,4):
    fig.add_trace(
        py.Scatter(
            x = t,
            y = change[i],
            name = name[i]))
    
fig.update_layout(
    yaxis = dict(title = 'Exchange rate (HUF/CHF)'), 
    xaxis = dict(title = 'ate'), 
    title = "HUF/CHF exchange values",
    updatemenus=[py.layout.Updatemenu(
        active=0,
        buttons=list(
            [dict(label = 'All value',
                  method = 'update',
                  args = [{'visible': [True, True, True, True]}]),
             dict(label = name[0],
                  method = 'update',
                  args = [{'visible': [True, False, False, False]}]),
             dict(label = name[1],
                  method = 'update',
                  args = [{'visible': [False, True, False, False]}]),
             dict(label = name[2],
                  method = 'update',
                  args = [{'visible': [False, False, True, False]}]),
             dict(label = name[3],
                  method = 'update',
                  args = [{'visible': [False, False, False, True]}]),
            ]),  
        pad={"r": 10, "t": 10},
        showactive=True,
        x=0.8,
        xanchor="left",
        y=1.0,
        yanchor="top"
        )])


fig.show()

Daily average of max and min:

In [6]:
fig = py.Figure()

fig.add_trace(
    py.Scatter(x=t,
               y=change[2],
               name="Daily maximum",
               line=dict(color="red")))

fig.add_trace(
    py.Scatter(x=t,
               y=np.mean(change[2]) * np.ones_like(t),
               name="Average daily maximum",
               line=dict(color="red", dash="dash")))

fig.add_trace(
    py.Scatter(x=t,
               y=change[3],
               name="Daily minimum",
               visible=False,
               line=dict(color="green")))

fig.add_trace(
    py.Scatter(x=t,
               y=np.mean(change[3]) * np.ones_like(t),
               name="Average daily minimum",
               visible=False,
               line=dict(color="green", dash="dash")))


fig.add_trace(
    py.Scatter(x=t,
               y=(change[3]+change[2])/2 * np.ones_like(t),
               name="Daily average",
               visible=False,
               line=dict(color="orange")))

fig.add_trace(
    py.Scatter(x=t,
               y=np.mean((change[3]+change[2])/2) * np.ones_like(t),
               name="Average",
               visible=False,
               line=dict(color="orange", dash="dash")))



# Buttons and average value
high_av = [dict(x="2015-01-01",
            y=np.mean(change[2]),
            xref="x", yref="y",
            text="Average maximum: %.6f" %np.mean(change[2]),
            ax=100, ay=-60)]

low_av = [dict(x="2021-01-27",
            y=np.mean(change[3]),
            xref="x", yref="y",
            text="Average minimum: %.6f" % np.mean(change[3]),
            ax=0, ay=50)]

av = [dict(x="2021-01-27",
            y=np.mean(change[3]),
            xref="x", yref="y",
            text="Average: %.6f" % np.mean((change[3]+change[2])/2),
            ax=0, ay=50)]

fig.update_layout(
    yaxis = dict(title = 'Exchange rate (HUF/CHF)'), 
    xaxis = dict(title = 'Date'),
    updatemenus=[
        dict(
            type="buttons",
            direction="right",
            active=0,
            x=1,
            y=1.2,
            buttons=list([
                dict(label="Average maximum",
                     method="update",
                     args=[{"visible": [True, True, False, False, False, False]},
                           {"title": "Average maximum",
                            "annotations": high_av}]),
                dict(label="Average minimum",
                     method="update",
                     args=[{"visible": [False, False, True, True, False, False]},
                           {"title": "Average minimum",
                            "annotations": low_av}]),
                dict(label="Daily average",
                     method="update",
                     args=[{"visible": [False, False, False, False, True, True]},
                           {"title": "Daily average",
                            "annotations": av}]),
                
            ]),
        )
    ])

# Title
fig.update_layout( title_text="Average maximum", xaxis_domain=[0.01, 1.0] )

fig.show()
In [7]:
np.mean((change[3]+change[2])/2)
Out[7]:
0.0034303627760252364

Selecting the time scale will help to better monitor the change in value:

In [8]:
# Create figure
fig = py.Figure()

change = [HC_open, HC_close, HC_high, HC_low]
name = ["Opening value", "Closing value", "Daily high value", "Daily low value"]
vis = [True, False, False, False]

for i in np.arange(0,4):
    fig.add_trace(
        py.Scatter(
            x = t,
            y = change[i],
            visible = vis[i],
            name = name[i] ))


# Set title
fig.update_layout( title_text="Exchange data with range slider and selectors", xaxis_domain=[0.01, 1.0])
    
# Add range slider
fig.update_layout(
    xaxis=dict(
        rangeselector=dict(
            buttons=list(
                [dict(count=1,
                     label="month",
                     step="month",
                     stepmode="backward"),
                dict(count=6,
                     label="half year",
                     step="month",
                     stepmode="backward"),
                dict(count=1,
                     label="YTD",
                     step="year",
                     stepmode="todate"),
                dict(count=1,
                     label="year",
                     step="year",
                     stepmode="backward"),
                dict(step="all"),])
        ),
        rangeslider=dict(
            visible=True
        ),
        type="date"
    )
)

fig.update_layout(
    yaxis = dict(title = 'Exchange rate (HUF/CHF)'), 
    xaxis = dict(title = 'Date'), 
    updatemenus=[py.layout.Updatemenu(
        active=0,
        buttons=list(
            [dict(label = name[0],
                  method = 'update',
                  args = [{'visible': [True, False, False, False]}]),
             dict(label = name[1],
                  method = 'update',
                  args = [{'visible': [False, True, False, False]}]),
             dict(label = name[2],
                  method = 'update',
                  args = [{'visible': [False, False, True, False]}]),
             dict(label = name[3],
                  method = 'update',
                  args = [{'visible': [False, False, False, True]}]),
            ]),  
        pad={"r": 10, "t": 10},
        showactive=True,
        x=0.8,
        xanchor="left",
        y=1.0,
        yanchor="top"
        )])

fig.show()

Histogram helps to recognize how many different values was in data. This shows how oscillating / stable the change value.

In [9]:
fig = py.Figure()
fig.update_layout(autosize=False, width=1000, height=500)

change = [HC_open, HC_close, HC_high, HC_low]
name = ["Opening value", "Closing value", "Daily high value", "Daily low value"]
years = [2015, 2016, 2017, 2018, 2019, 2020, 2021]
#months = [January, February, March, April, May, June, July, August, September, October, November, December]
months1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

for i in np.arange(0,4):
    fig.add_trace(
        py.Histogram(
            x = change[i],
            name=name[i]))

fig.update_layout(
    yaxis = dict(title = 'Counts'), 
    xaxis = dict(title = 'Exchange rate (HUF/CHF)'), 
    title = "HUF/CHF exchange values histogram",
    updatemenus=[py.layout.Updatemenu(
        active=0,
        buttons=list(
            [dict(label = 'All value',
                  method = 'update',
                  args = [{'visible': [True, True, True, True]}]),
             dict(label = name[0],
                  method = 'update',
                  args = [{'visible': [True, False, False, False]}]),
             dict(label = name[1],
                  method = 'update',
                  args = [{'visible': [False, True, False, False]}]),
             dict(label = name[2],
                  method = 'update',
                  args = [{'visible': [False, False, True, False]}]),
             dict(label = name[3],
                  method = 'update',
                  args = [{'visible': [False, False, False, True]}]),
            ]),  
        pad={"r": 10, "t": 10},
        showactive=True,
        x=0.8,
        xanchor="left",
        y=1.0,
        yanchor="top"
        )])
In [ ]: